home *** CD-ROM | disk | FTP | other *** search
-
- Listing 1 -- xstoul.c
-
-
- /* _Stoul function */
- #include <stdlib.h>
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- #include <stddef.h>
- #include <string.h>
-
- /* macros */
- #define BASE_MAX 36 /* largest valid base */
- /* static data */
- static const char digits[] = { /* valid digits */
- "0123456789abcdefghijklmnopqrstuvwxyz"};
- static const char ndigs[BASE_MAX+1] = { /* 32-bits! */
- 0, 0, 33, 21, 17, 14, 13, 12, 11, 11,
- 10, 10, 9, 9, 9, 9, 9, 8, 8, 8,
- 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7,};
-
- unsigned long _Stoul(const char *s, char **endptr, int base)
- { /* convert string to unsigned long, with checking */
- const char *sc, *sd;
- const char *s1, *s2;
- char sign;
- ptrdiff_t n;
- unsigned long x, y;
-
- for (sc = s; isspace(*sc); ++sc)
- ;
- sign = *sc == '-' || *sc == '+' ? *sc++ : '+';
- if (base < 0 || base == 1 || BASE_MAX < base)
- { /* silly base */
- if (endptr)
- *endptr = (char *)s;
- return (0);
- }
- else if (base)
- { /* strip 0x or 0X */
- if (base == 16 && *sc == '0'
- && (sc[1] == 'x' || sc[1] == 'X'))
- sc += 2;
- }
- else if (*sc != '0')
- base = 10;
- else if (sc[1] == 'x' || sc[1] == 'X')
- base = 16, sc += 2;
- else
- base = 8;
- for (s1 = sc; *sc == '0'; ++sc)
- ; /* skip leading zeros */
- x = 0;
- for (s2 = sc; (sd = (char *)memchr(digits,
- tolower(*sc), base)) != NULL; ++sc)
- { /* accumulate digits */
- y = x; /* for overflow checking */
- x = x * base + (sd - digits);
- }
- if (s1 == sc)
- { /* check string validity */
- if (endptr)
- *endptr = (char *)s;
- return (0);
- }
- n = sc - s2 - ndigs[base];
- if (n < 0)
- ;
- else if (0 < n || x < x - sc[-1]
- || (x - sc[-1]) / base != y)
- { /* overflow */
- errno = ERANGE;
- x = ULONG_MAX;
- }
- if (sign == '-') /* get final value */
- x = -x;
- if (endptr)
- *endptr = (char *)sc;
- return (x);
- }
-
-